package com.panfeng.xcloud.scheduler.jobs;

import com.alibaba.fastjson.JSON;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.panfeng.xcloud.common.core.constants.Constants;
import com.panfeng.xcloud.common.core.utils.UuidUtils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;

import java.util.HashMap;
import java.util.Map;

/**
 * 任务基类
 *
 * @author xiaobo
 * @version 1.0
 * @since 2019-8-26
 */
@Slf4j
public abstract class BaseSimpleJob implements SimpleJob {

    private static final ThreadLocal<Long> taskExcuteTimeDuration = new ThreadLocal<>();

    protected abstract void doJob(ShardingContext shardingContext);

    public void doJobBefore(ShardingContext shardingContext) {
        Long startTime = System.currentTimeMillis();
        taskExcuteTimeDuration.set(startTime);
        String generateUUID = UuidUtils.generateUUID() + startTime;
        MDC.put(Constants.MDC_KEY, "uuid_" + generateUUID);
        log.info(String.format(">>> 任务clazz: %s-当前线程ID: %s, 任务总片数: %s, 当前分片项: %s", this.getClass().getName(), Thread.currentThread().getId(), shardingContext.getShardingTotalCount(), shardingContext.getShardingItem()));
    }

    @Override
    public void execute(ShardingContext shardingContext) {
        this.doJobBefore(shardingContext);
        this.doJob(shardingContext);
        this.doJobAfter(shardingContext);
    }

    public void doJobAfter(ShardingContext shardingContext) {
        Long startTime = taskExcuteTimeDuration.get();
        startTime = null != startTime ? startTime : 0L;
        Long endTime = System.currentTimeMillis();
        log.info(">>> 任务clazz:{} =>开始时间：{} =>结束时间：{} =>耗时：{}毫秒 <<<", this.getClass().getName(), startTime, endTime, (endTime - startTime));
    }

    /**
     * 构造任务分片上下文参数
     *
     * @param shardingContext
     * @return
     */
    protected Map<String, Object> buildShardingParam(ShardingContext shardingContext) {
        Map<String, Object> paramMap = new HashMap<String, Object>();

        //任务总片数
        paramMap.put("shardingTotalCount", shardingContext.getShardingTotalCount());
        //当前分片项
        paramMap.put("shardingItem", shardingContext.getShardingItem());

        log.info(">>> 构建的任务分片参数：{} <<<", JSON.toJSONString(paramMap));
        return paramMap;
    }
}
